#include "AudioDecode.h"
#include "mediaPriv.h"


namespace Media{

std::map<int, AudioDecode *> AudioDecode::sm_decoderMap;
std::recursive_mutex 		 AudioDecode::sm_mapMutex;

AudioDecode *AudioDecode::instance(int channel)
{
    if(channel > ADEC_SUPPORT_CHN - 1)
    {
        errorf("channel is over VDEC_MAX_CHN_NUM \n");
        return NULL;
    }
    
    std::lock_guard<std::recursive_mutex> guard(sm_mapMutex);
    
	if(sm_decoderMap.find(channel) == sm_decoderMap.end())
	{
		sm_decoderMap[channel] = new AudioDecode(channel);
	}

	return sm_decoderMap[channel];
}


AudioDecode::AudioDecode(int channel) 
: m_channel(channel)
, m_started(false)
{
	if(!createDecoder())
	{
		errorf("AudioDecode create error! channel %d", m_channel);
		return ;
	}
	//tracef("createAudioDecoder %d success\n", channel);
	
	if(!decodeInit())
	{
		errorf("Init failed");
	}
}

bool AudioDecode::createDecoder()
{
    int status;
    AudioDecDesc decDesc;

    decDesc.card = 0;
    decDesc.channel = m_channel;
    status = createAudioDecoder(&decDesc, &m_audioDecoder);
    if (status)
    {
        return false;
    }

    return true;
}

bool AudioDecode::decodeInit()
{
    AudioDecFormat decFormat;
    memset(&decFormat, 0, sizeof(AudioDecFormat));
    decFormat.type = audioEncAAC;
	decFormat.frequency = 32000; //32000;44100
	decFormat.depth = 16;
    
    if(!setFormat(&decFormat))
    {
    	return false;
    }
    return true;
}

bool AudioDecode::getFormat(AudioDecFormat *format)
{
	if(!format)
	{
	    errorf("format is NULL \n");
		return false;
	}	
	memcpy(format, &m_format, sizeof(AudioDecFormat));
	return true;
}

bool AudioDecode::setFormat(AudioDecFormat *format)
{
    if(!format || !m_audioDecoder)
	{
	    errorf("format or m_audioDecoder is NULL \n");
		return false;
	}
		
    return (m_audioDecoder->setFormat(m_audioDecoder, format) >= 0);
}

bool AudioDecode::start()
{
    if(!m_audioDecoder)
	{
	    errorf("m_audioDecoder is NULL \n");
		return false;
	}
    if(!m_started)
    {
        int ret = m_audioDecoder->start(m_audioDecoder);
    	if(ret)
    	{
    		return false;
    	}
    	m_started = true;
    }
	return true;
}

bool AudioDecode::stop()
{
    if(!m_audioDecoder)
	{
	    errorf("m_audioDecoder is NULL \n");
		return false;
	}
	if(m_started)
    {
        int ret = m_audioDecoder->stop(m_audioDecoder);
    	if(ret)
    	{
    		return false;
    	}
    	m_started = false;
    }
	return true;
}

bool AudioDecode::putPacket(AudioDecPacket *packet)
{
    if(!packet || !m_audioDecoder)
	{
	    errorf("packet or m_audioDecoderis NULL \n");
		return false;
	}
		
    return (m_audioDecoder->putPacket(m_audioDecoder,packet) >= 0);
}

}


